﻿using Blm.Utils.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using VisionCloud.Domain.Common;
using VisionCloud.Utility.Extensions;

namespace VisionCloud.Domain.DtoModel.Ms
{
    public class ProjectProgressDetailRequestDto
    {
        /// <summary>
        /// 项目Id，必填
        /// </summary>
        public Guid ProjectId { set; get; }

        /// <summary>
        /// 阶段枚举按位或
        /// </summary>
        public List<ProjectMeasureStepEnum> ProjectStepArray { set; get; }

        /// <summary>
        /// 自检、巡检类型
        /// </summary>
        public int Type { set; get; }

        /// <summary>
        /// 楼栋名
        /// </summary>
        public string BuildingName { set; get; }
    }

    public class ProjectProgressDetailResponseDto
    {
        public List<ProjectStepProgressDetailDto> ProjectSteps { set; get; }

        public List<BuildingMeasureInfo> BuildingMeasureInfos { set; get; }

        /// <summary>
        /// 合计测量面积
        /// </summary>
        public double MeasureTotalArea
        {
            get
            {
                return ProjectSteps.Sum(x => x.MeasureArea);
            }
        }

        /// <summary>
        /// 合计测量进度
        /// </summary>
        public double MeasureTotalProgress
        {
            get
            {
                var percent = (MeasureTotalArea * 100) / (ProjectSteps.FirstOrDefault()?.MapArea * 4 * ProjectSteps.FirstOrDefault()?.TotalFloor);
                return percent.HasValue ? Math.Round(percent.Value, 1) : 0;
            }
        }

        /// <summary>
        /// 楼栋名
        /// </summary>
        public List<string> Buildings
        {
            get
            {
                return BuildingMeasureInfos?.Select(x => x.BuildingNum.ToString()).ToList();
            }
        }

        public void SetFloors(List<Core.Model.Ms.MsSProgressAnalysis> progressAnalysisList, List<string> projectTypes)
        {
            if (ProjectSteps.Count < 1) return;
            if (projectTypes == null) projectTypes = new List<string>();
            progressAnalysisList.ForEach(x =>
            {
                var build = BuildingMeasureInfos.Where(b => b.BuildingNum == x.BuildingName).FirstOrDefault();
                FloorMeasureInfo floor = null;
                var mapArea = ProjectSteps.FirstOrDefault().MapArea;
                if (x.StructuralFirstDateTime.HasValue)
                {
                    if (build != null)
                    {
                        floor = build.FloorMeasureInfos.FirstOrDefault(f => f.FloorNum == x.FloorNum);
                        if (floor != null)
                        {
                            floor.StructuralFirstDateTimeStr = x.StructuralFirstDateTime.Value.ToString("yyyy-MM-dd");
                        }
                        else
                        {
                            floor = new FloorMeasureInfo { FloorNum = x.FloorNum, MapArea = mapArea, StructuralFirstDateTimeStr = x.StructuralFirstDateTime.Value.ToString("yyyy-MM-dd") };
                            build.FloorMeasureInfos.Add(floor);
                        }
                    }
                    var value = ProjectSteps.Where(p => p.ProjectStep == ProjectMeasureStepEnum.结构初测).FirstOrDefault();
                    if (value != null && (projectTypes.Count < 1 || projectTypes.Contains(x.StructuralFirstDateTimeTaskType)))
                    {
                        value.MeasureArea += value.MapArea;
                        value.ProjectFloors.Add(x.FloorNum);
                    }
                }
                if (x.StructuralSecondDateTime.HasValue)
                {
                    if (build != null)
                    {
                        if (floor != null)
                        {
                            floor.StructuralSecondDateTimeStr = x.StructuralSecondDateTime.Value.ToString("yyyy-MM-dd");
                        }
                        else
                        {
                            floor = new FloorMeasureInfo { FloorNum = x.FloorNum, MapArea = mapArea, StructuralSecondDateTimeStr = x.StructuralSecondDateTime.Value.ToString("yyyy-MM-dd") };
                            build.FloorMeasureInfos.Add(floor);
                        }
                    }
                    var value = ProjectSteps.Where(p => p.ProjectStep == ProjectMeasureStepEnum.结构复测).FirstOrDefault();
                    if (value != null && (projectTypes.Count < 1 || projectTypes.Contains(x.StructuralFirstDateTimeTaskType)))
                    {
                        value.MeasureArea += value.MapArea;
                        value.ProjectFloors.Add(x.FloorNum);
                    }
                }
                if (x.PlasterFirstDateTime.HasValue)
                {
                    if (build != null)
                    {
                        if (floor != null)
                        {
                            floor.PlasterFirstDateTimeStr = x.PlasterFirstDateTime.Value.ToString("yyyy-MM-dd");
                        }
                        else
                        {
                            floor = new FloorMeasureInfo { FloorNum = x.FloorNum, MapArea = mapArea, PlasterFirstDateTimeStr = x.PlasterFirstDateTime.Value.ToString("yyyy-MM-dd") };
                            build.FloorMeasureInfos.Add(floor);
                        }
                    }
                    var value = ProjectSteps.Where(p => p.ProjectStep == ProjectMeasureStepEnum.抹灰初测).FirstOrDefault();
                    if (value != null && (projectTypes.Count < 1 || projectTypes.Contains(x.PlasterFirstDateTimeTaskType)))
                    {
                        value.MeasureArea += value.MapArea;
                        value.ProjectFloors.Add(x.FloorNum);
                    }
                }
                if (x.PlasterSecondDateTime.HasValue)
                {
                    if (build != null)
                    {
                        if (floor != null)
                        {
                            floor.PlasterSecondDateTimeStr = x.PlasterSecondDateTime.Value.ToString("yyyy-MM-dd");
                        }
                        else
                        {
                            floor = new FloorMeasureInfo { FloorNum = x.FloorNum, MapArea = mapArea, PlasterSecondDateTimeStr = x.PlasterSecondDateTime.Value.ToString("yyyy-MM-dd") };
                            build.FloorMeasureInfos.Add(floor);
                        }
                    }
                    var value = ProjectSteps.Where(p => p.ProjectStep == ProjectMeasureStepEnum.抹灰复测).FirstOrDefault();
                    if (value != null && (projectTypes.Count < 1 || projectTypes.Contains(x.PlasterSecondDateTimeTaskType)))
                    {
                        value.MeasureArea += value.MapArea;
                        value.ProjectFloors.Add(x.FloorNum);
                    }
                }
                if (x.MasonryFirstDateTime.HasValue)
                {
                    if (build != null)
                    {
                        if (floor != null)
                        {
                            floor.MasonryFirstDateTimeStr = x.MasonryFirstDateTime.Value.ToString("yyyy-MM-dd");
                        }
                        else
                        {
                            floor = new FloorMeasureInfo { FloorNum = x.FloorNum, MapArea = mapArea, MasonryFirstDateTimeStr = x.MasonryFirstDateTime.Value.ToString("yyyy-MM-dd") };
                            build.FloorMeasureInfos.Add(floor);
                        }
                    }
                    var value = ProjectSteps.Where(p => p.ProjectStep == ProjectMeasureStepEnum.砌筑初测).FirstOrDefault();
                    if (value != null && (projectTypes.Count < 1 || projectTypes.Contains(x.MasonryFirstDateTimeTaskType)))
                    {
                        value.MeasureArea += value.MapArea;
                        value.ProjectFloors.Add(x.FloorNum);
                    }
                }
                if (x.MasonrySecondDateTime.HasValue)
                {
                    if (build != null)
                    {
                        if (floor != null)
                        {
                            floor.MasonrySecondDateTimeStr = x.MasonrySecondDateTime.Value.ToString("yyyy-MM-dd");
                        }
                        else
                        {
                            floor = new FloorMeasureInfo { FloorNum = x.FloorNum, MapArea = mapArea, StructuralFirstDateTimeStr = x.MasonrySecondDateTime.Value.ToString("yyyy-MM-dd") };
                            build.FloorMeasureInfos.Add(floor);
                        }
                    }
                    var value = ProjectSteps.Where(p => p.ProjectStep == ProjectMeasureStepEnum.砌筑复测).FirstOrDefault();
                    if (value != null && (projectTypes.Count < 1 || projectTypes.Contains(x.MasonrySecondDateTimeTaskType)))
                    {
                        value.MeasureArea += value.MapArea;
                        value.ProjectFloors.Add(x.FloorNum);
                    }
                }
                build?.FloorMeasureInfos.Sort((a, b) => { return a.FloorNum.ToInt() - b.FloorNum.ToInt(); });
            });
        }
    }

    public class ProjectStepProgressDetailDto
    {
        public double MapArea { set; get; }
        public int TotalFloor { set; get; }

        /// <summary>
        /// 阶段枚举值
        /// </summary>
        public ProjectMeasureStepEnum ProjectStep { set; get; }

        /// <summary>
        /// 当前测量面积
        /// </summary>
        public double MeasureArea { set; get; }

        /// <summary>
        /// 测量进度，百分比值
        /// </summary>
        public double MeasureProgress
        {
            get
            {
                double percent = (MeasureArea * 100) / (MapArea * TotalFloor);
                return MapArea == 0 ? 0.0 : Math.Round(percent, 1);
            }
        }

        /// <summary>
        /// 已测层
        /// </summary>
        public List<string> ProjectFloors { set; get; }
    }

    /// <summary>
    /// 项目楼栋测量进度
    /// </summary>
    public class BuildingMeasureInfo
    {
        public string BuildingNum { set; get; }

        /// <summary>
        /// 楼栋总层数
        /// </summary>
        public int FloorNum { set; get; }

        /// <summary>
        /// 结构初测已测层数
        /// </summary>
        public int StructuralFirstCount
        {
            get
            {
                return FloorMeasureInfos.Count(x => !x.StructuralFirstDateTimeStr.IsNullOrWhiteSpace());
            }
        }

        /// <summary>
        /// 结构复测已测层数
        /// </summary>
        public int StructuralSecondCount
        {
            get
            {
                return FloorMeasureInfos.Count(x => !x.StructuralSecondDateTimeStr.IsNullOrWhiteSpace());
            }
        }

        /// <summary>
        /// 抹灰工程已测层数
        /// </summary>
        public int PlasterCount
        {
            get
            {
                return FloorMeasureInfos.Count(x => !x.PlasterSecondDateTimeStr.IsNullOrWhiteSpace() || !x.PlasterFirstDateTimeStr.IsNullOrWhiteSpace());
            }
        }

        /// <summary>
        /// 砌筑工程已测层数
        /// </summary>
        public int MasonryCount
        {
            get
            {
                return FloorMeasureInfos.Count(x => !x.MasonryFirstDateTimeStr.IsNullOrWhiteSpace() || !x.MasonrySecondDateTimeStr.IsNullOrWhiteSpace());
            }
        }

        /// <summary>
        /// 层测量信息
        /// </summary>
        public List<FloorMeasureInfo> FloorMeasureInfos { set; get; }
    }

    public class FloorMeasureInfo
    {
        public string FloorNum { set; get; }
        public string StructuralFirstDateTimeStr { set; get; }
        public string StructuralSecondDateTimeStr { set; get; }
        public string PlasterFirstDateTimeStr { set; get; }
        public string PlasterSecondDateTimeStr { set; get; }
        public string MasonrySecondDateTimeStr { set; get; }
        public string MasonryFirstDateTimeStr { set; get; }

        /// <summary>
        /// 建筑面积
        /// </summary>
        public double MapArea { set; get; }
    }
}